using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Profiling;
using Unity.Transforms;

namespace DOTS.DOD.LESSON7
{
    [BurstCompile]
    [RequireMatchingQueriesForUpdate]
    [UpdateInGroup(typeof(CubesMarchSystemGroup))]
    [UpdateAfter(typeof(CubesGeneratorSystem))]
    partial struct CubesMarchingSystem : ISystem
    {
        static readonly ProfilerMarker mProfilerMarker = new ProfilerMarker("CubesMarchWithDots");
        EntityQuery mCubesQuery;
        ComponentTypeHandle<LocalTransform> mTransformTypeHandle;
        ComponentTypeHandle<RotateSpeed> mRotateSpeedTypeHandle;

        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
            state.RequireForUpdate<RotateSpeed>();
            state.RequireForUpdate<MovementSpeed>();

            //创建一个忽略组件禁用的查询器：
            var queryBuilder = new EntityQueryBuilder(Allocator.Temp).WithAll<RotateSpeed, MovementSpeed>()
                .WithOptions(EntityQueryOptions.IgnoreComponentEnabledState);
            mCubesQuery = state.GetEntityQuery(queryBuilder);

            mTransformTypeHandle = state.GetComponentTypeHandle<LocalTransform>();
            mRotateSpeedTypeHandle = state.GetComponentTypeHandle<RotateSpeed>();
        }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            using (mProfilerMarker.Auto())
            {
                var generator = SystemAPI.GetSingleton<CubeGenerator>();
                mTransformTypeHandle.Update(ref state);
                mRotateSpeedTypeHandle.Update(ref state);

                var stopRotateJob = new StopCubesRotateChunkJob()
                {
                    DeltaTime = SystemAPI.Time.DeltaTime,
                    ElapsedTime = (float) SystemAPI.Time.ElapsedTime,
                    LeftRightBound = new float2(generator.GeneratorAreaPos.x * 0.5f, generator.TargetAreaPos.x * 0.5f),
                    TransformTypeHandle = mTransformTypeHandle,
                    RotateSpeedTypeHandle = mRotateSpeedTypeHandle,
                };
                state.Dependency = stopRotateJob.ScheduleParallel(mCubesQuery, state.Dependency);

                EntityCommandBuffer ecb = new EntityCommandBuffer(Allocator.TempJob);
                EntityCommandBuffer.ParallelWriter ecb_parallel = ecb.AsParallelWriter();
                var marchingJob = new CubesMarchingEntityJob()
                {
                    DeltaTime = SystemAPI.Time.DeltaTime,
                    ECB_Parallel = ecb_parallel,
                };
                state.Dependency = marchingJob.ScheduleParallel(mCubesQuery, state.Dependency);
                state.Dependency.Complete();
                ecb.Playback(state.EntityManager);
                ecb.Dispose();
            }
        }
    }
}